﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AO.Core;

namespace ZoneEngine.Functions
{
    class Function_lineteleport : FunctionPrototype
    {
        public new int FunctionNumber = 53059;
        
        public new string FunctionName = "lineteleport";
        
        public override int ReturnNumber()
        { 
            return FunctionNumber; 
        }
        
        public override bool Execute(Dynel Self, Dynel Caller, object Target, object[] Arguments)
        {
            lock (Self)
            {
                lock (Caller)
                {
                    lock (Target)
                    {
                        return FunctionExecute(Self, Caller, Target, Arguments);
                    }
                }
            }
        }
        
        public override string ReturnName()
        {
            return FunctionName;
        }
        /// <summary>
        /// Lineteleport
        /// </summary>
        /// <param name="Self"></param>
        /// <param name="Caller"></param>
        /// <param name="Target"></param>
        /// <param name="Arguments">UInt32 (LineType?), UInt32 (Combo of Line# and Playfield), Int32 (Playfield to teleport to)</param>
        /// <returns></returns>
        public bool FunctionExecute(Dynel Self, Dynel Caller, object Target, object[] Arguments)
        {
            uint arg2;
            int to_pf;
            Console.WriteLine(Target.GetType().ToString());
            if (Target is Statels.Statel)
            {
                arg2 = UInt32.Parse((string)Arguments[1]); // Linesegment and playfield (lower word)
                arg2 = arg2 >> 16;
                to_pf = Int32.Parse((string)Arguments[2]);
            }
            else
            {
                arg2 = (UInt32)Arguments[1];
                to_pf = (Int32)Arguments[2];
            }
            coordheading a = FindEntry(to_pf, (Int32)arg2);
            if (a.Coordinates.x != -1)
            {
                ((Character)Self).client.Teleport(a.Coordinates, a.Heading, to_pf);
                return true;
            }
            return false; 
        }

        public coordheading FindEntry(int Playfield, int DestinationNumber)
        {
            coordheading ret = new coordheading();
            ret.Coordinates.x = -1;
            foreach (Collision.WallCollision.Line l in Collision.WallCollision.destinations[Playfield].playfield.lines)
            {
                if (l.ID != DestinationNumber)
                {
                    continue;
                }
                ret.Coordinates.x = (l.start.X + l.end.X) / 2;
                ret.Coordinates.y = (l.start.Y + l.end.Y) / 2;
                ret.Coordinates.z = (l.start.Z + l.end.Z) / 2;
                // TODO: Calculate the right Quaternion for the heading...
                // - Algorithman
                Quaternion q = new Quaternion(new Vector3((l.end.X - l.start.X), 1, -(l.end.Z - l.start.Z)));
                ret.Heading.x = q.x;
                ret.Heading.y = q.y;
                ret.Heading.z = q.z;
                ret.Heading.w = q.w;
            }
            return ret;
        }

    }
}
